<script>
import NodeIconSidebar from "./components/NodeIconSidebar.vue"
import SidebarTrigger from "./components/SidebarTrigger.vue"
import SideBarTheme from "./components/Theme.vue"
import SideBarStyle from "./components/Style.vue"
import SideBarBaseStyle from "./components/BaseStyle.vue"
import SideBarStructure from "./components/Structure.vue"
import SidebarOutline from "./components/OutlineSidebar.vue"
import SidebarHistory from "./components/History.vue"
import OutlineEdit from "./components/OutlineEdit.vue"
import SidebarShortcutKey from "./components/ShortcutKey.vue"
// import NavigatorToolbar from "./components/NavigatorToolbar.vue"
// import Count from "./components/Count.vue"
import Search from "./components/Search.vue"
import FooterBar from "./components/FooterBar/index.vue"

import NodeImage from "./components/NodeImage.vue"
import NodeHyperlink from "./components/NodeHyperlink.vue"
import NodeIcon from "./components/NodeIcon.vue"
import NodeNote from "./components/NodeNote.vue"
import NodeTag from "./components/NodeTag.vue"
import Export from "./components/Export.vue"
import Import from "./components/Import.vue"
import ToolbarNodeBtnList from "./components/ToolbarNodeBtnList.vue"

import { ElNotification } from "element-plus"
import exampleData from "simple-mind-map/example/exampleData"
import { throttle } from "simple-mind-map/src/utils/index"
import { useMind } from "@mind/store"
import { mapState, mapActions } from "pinia"

let fileHandle = null
export default {
  name: "Toolbar",
  components: {
    NodeIconSidebar,
    SidebarTrigger,
    SideBarTheme,
    SideBarStyle,
    SideBarBaseStyle,
    SideBarStructure,
    SidebarOutline,
    OutlineEdit,
    SidebarShortcutKey,
    FooterBar,
    SidebarHistory,
    // NavigatorToolbar,
    // Count,
    Search,
    NodeImage,
    NodeHyperlink,
    NodeIcon,
    NodeNote,
    NodeTag,
    Export,
    Import,
    ToolbarNodeBtnList
  },
  data() {
    return {
      list: [
        "back",
        "forward",
        "painter",
        "siblingNode",
        "childNode",
        "deleteNode",
        "image",
        "icon",
        "link",
        "note",
        "tag",
        "summary",
        "associativeLine",
        "formula"
      ],
      horizontalList: [],
      verticalList: [],
      showMoreBtn: false
    }
  },
  computed: {
    ...mapState(useMind, ["isHandleLocalFile", "isDark"])
  },

  created() {
    this.$bus.$on("write_local_file", this.onWriteLocalFile)
  },
  mounted() {
    this.computeToolbarShow()
    this.computeToolbarShowThrottle = throttle(this.computeToolbarShow, 300)
    window.addEventListener("resize", this.computeToolbarShowThrottle)
    this.$bus.$on("lang_change", this.computeToolbarShowThrottle)
  },
  beforeUnmount() {
    // this.$bus.$off("write_local_file", this.onWriteLocalFile)
    window.removeEventListener("resize", this.computeToolbarShowThrottle)
    this.$bus.$off("lang_change", this.computeToolbarShowThrottle)
  },
  methods: {
    ...mapActions(useMind, ["setIsHandleLocalFile"]),
    toolbarDone() {
      this.showMoreBtn = false
    },
    // 计算工具按钮如何显示
    computeToolbarShow() {
      const windowWidth = window.innerWidth - 380
      const all = [...this.list]
      let index = 1
      const loopCheck = async () => {
        if (index > all.length) {
          this.toolbarDone()
          return
        }
        this.horizontalList = all.slice(0, index)
        await this.$nextTick()
        const width = this.$refs.toolbarRef.offsetWidth

        if (width < windowWidth) {
          index++
          await loopCheck()
        } else if (index > 0 && width > windowWidth) {
          index--
          this.horizontalList = all.slice(0, index)
          done()
        }
      }
      const done = () => {
        this.verticalList = all.slice(index)
        this.showMoreBtn = this.verticalList.length > 0
      }
      loopCheck()
    },

    // 监听本地文件读写
    onWriteLocalFile(content) {
      clearTimeout(this.timer)
      this.timer = setTimeout(() => {
        this.writeLocalFile(content)
      }, 1000)
    },

    // 打开本地文件
    async openLocalFile() {
      try {
        const [_fileHandle] = await window.showOpenFilePicker({
          types: [
            {
              description: "",
              accept: {
                "application/json": [".smm"]
              }
            }
          ],
          excludeAcceptAllOption: true,
          multiple: false
        })
        if (!_fileHandle) {
          return
        }
        fileHandle = _fileHandle
        if (fileHandle.kind === "directory") {
          this.$message.warning(this.$t("toolbar.selectFileTip"))
          return
        }
        this.readFile()
      } catch (error) {
        console.log(error)
        if (error.toString().includes("aborted")) {
          return
        }
        this.$message.warning(this.$t("toolbar.notSupportTip"))
      }
    },

    // 读取本地文件
    async readFile() {
      const file = await fileHandle.getFile()
      const fileReader = new FileReader()
      fileReader.onload = async () => {
        this.setIsHandleLocalFile(true)
        this.setData(fileReader.result)
        ElNotification({
          title: "",
          message: `${this.$t("toolbar.editingLocalFileTipFront")}${file.name}${this.$t(
            "toolbar.editingLocalFileTipEnd"
          )}`,
          duration: 0,
          showClose: true
        })
      }
      fileReader.readAsText(file)
    },

    // 渲染读取的数据
    setData(str) {
      try {
        let data = JSON.parse(str)
        if (typeof data !== "object") {
          throw new Error("文件错误")
        }
        if (data.root) {
          this.isFullDataFile = true
        } else {
          this.isFullDataFile = false
          data = {
            ...exampleData,
            root: data
          }
        }
        console.log("data", data)
        this.$bus.$emit("setData", data)
      } catch (error) {
        console.log(error)
        this.$message.error(this.$t("toolbar.fileOpenFailed"))
      }
    },

    // 写入本地文件
    async writeLocalFile(content) {
      if (!fileHandle || !this.isHandleLocalFile) {
        return
      }
      if (!this.isFullDataFile) {
        content = content.root
      }
      const string = JSON.stringify(content)
      this.setIsHandleLocalFile(true)
      const writable = await fileHandle.createWritable()
      await writable.write(string)
      await writable.close()
    },

    // 创建本地文件
    async createNewLocalFile() {
      await this.createLocalFile(exampleData)
    },

    // 另存为
    async saveLocalFile() {
      const data = this.$bus.mindMap.getData(true)
      console.log("data", data)
      await this.createLocalFile(data)
    },

    // 创建本地文件
    async createLocalFile(content) {
      try {
        const _fileHandle = await window.showSaveFilePicker({
          types: [
            {
              description: "",
              accept: { "application/json": [".smm"] }
            }
          ],
          suggestedName: "思维导图"
        })
        if (!_fileHandle) {
          return
        }
        const loading = this.$loading({
          lock: true,
          text: "正在创建文件"
        })
        fileHandle = _fileHandle
        this.setIsHandleLocalFile(true)
        this.isFullDataFile = true
        await this.writeLocalFile(content)
        await this.readFile()
        loading.close()
      } catch (error) {
        console.log(error)
        if (error.toString().includes("aborted")) {
          return
        }
        this.$message.warning("不支持")
      }
    }
  }
}
</script>
<template>
  <div :class="['toolbarContainer', { isDark }]">
    <div class="toolbar" ref="toolbarRef">
      <!-- 节点操作 -->
      <div class="toolbarBlock not-right">
        <ToolbarNodeBtnList :list="horizontalList" />
        <!-- 更多 -->
        <el-popover
          v-if="showMoreBtn"
          placement="bottom-end"
          width="120"
          trigger="hover"
          :style="{ marginLeft: horizontalList.length > 0 ? '20px' : 0 }"
        >
          <ToolbarNodeBtnList dir="v" :list="verticalList" />
          <template #reference>
            <div class="toolbarBtn">
              <span class="icon iconfont-chaojizhiku iconlianjiexian" />
              <span class="text">更多</span>
            </div>
          </template>
        </el-popover>
      </div>
      <!-- 导出 -->
      <div class="toolbarBlock">
        <div class="toolbarBtn" @click="createNewLocalFile">
          <span class="icon iconfont-chaojizhiku iconxinjian" />
          <span class="text">新建</span>
        </div>
        <div class="toolbarBtn" @click="openLocalFile">
          <span class="icon iconfont-chaojizhiku icondakai" />
          <span class="text">打开</span>
        </div>
        <div class="toolbarBtn" @click="saveLocalFile">
          <span class="icon iconfont-chaojizhiku iconlingcunwei" />
          <span class="text">另保存</span>
        </div>
        <div class="toolbarBtn" @click="$bus.$emit('showImport')">
          <span class="icon iconfont-chaojizhiku icondaoru" />
          <span class="text">导入</span>
        </div>
        <div class="toolbarBtn" @click="$bus.$emit('showExport')">
          <span class="icon iconfont-chaojizhiku iconexport" />
          <span class="text">导出</span>
        </div>
      </div>
    </div>
    <NodeImage />
    <NodeHyperlink />
    <NodeIcon />
    <NodeNote />
    <NodeTag />
    <Export />
    <Import />
  </div>

  <NodeIconSidebar />
  <SidebarTrigger />
  <!-- 主题 -->
  <SideBarTheme />
  <!-- 样式 -->
  <SideBarStyle />
  <!-- 基础样式 -->
  <SideBarBaseStyle />
  <!-- 结构 -->
  <SideBarStructure />
  <!-- 大纲 -->
  <OutlineEdit />
  <SidebarOutline />
  <!-- 快捷键 -->
  <SidebarShortcutKey />
  <!-- 历史记录 -->
  <SidebarHistory />
  <!-- 搜索 -->
  <Search />
  <!-- 底部栏 -->
  <FooterBar />
  <!-- <FormulaSidebar /> -->
  <!-- <NodeIconToolbar /> -->
</template>
<style lang="less" scoped>
.toolbarContainer {
  position: relative;
  width: 100%;
  height: 100%;
  &.isDark {
    .toolbar {
      color: hsla(0, 0%, 100%, 0.9);
      .toolbarBlock {
        background-color: #262a2e;
      }

      .toolbarBtn {
        .icon {
          background: transparent;
          border-color: transparent;
        }

        &:hover {
          &:not(.disabled) {
            .icon {
              background: hsla(0, 0%, 100%, 0.05);
            }
          }
        }

        &.disabled {
          color: #54595f;
        }
      }
    }
  }
  .toolbar {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    top: 20px;
    width: max-content;
    display: flex;
    font-size: 12px;
    font-family:
      PingFangSC-Regular,
      PingFang SC;
    font-weight: 400;
    color: rgba(26, 26, 26, 0.8);
    z-index: 2;

    .toolbarBlock {
      display: flex;
      background-color: #fff;
      padding: 10px 20px;
      border-radius: 6px;
      box-shadow: 0 2px 16px 0 rgba(0, 0, 0, 0.06);
      border: 1px solid rgba(0, 0, 0, 0.06);
      margin-right: 20px;
      flex-shrink: 0;

      &:last-of-type {
        margin-right: 0;
      }
    }

    .toolbarBtn {
      display: flex;
      justify-content: center;
      flex-direction: column;
      cursor: pointer;
      margin-right: 20px;

      &:last-of-type {
        margin-right: 0;
      }

      &:hover {
        &:not(.disabled) {
          .icon {
            background: #f5f5f5;
          }
        }
      }

      &.active {
        .icon {
          background: #f5f5f5;
        }
      }

      &.disabled {
        color: #bcbcbc;
        cursor: not-allowed;
        pointer-events: none;
      }

      .icon {
        display: flex;
        height: 26px;
        background: #fff;
        border-radius: 4px;
        border: 1px solid #e9e9e9;
        justify-content: center;
        flex-direction: column;
        text-align: center;
        padding: 0 5px;
      }

      .text {
        margin-top: 3px;
      }
    }
  }
}
</style>
